import type { Preset, SourceCodeTransformer } from 'unocss'
import fs from 'node:fs'
import path from 'node:path'
import { blue as brands, gold, green, presetPrimaryColors, red } from '@ant-design/colors'
// loader helpers -- pnpm i @iconify/utils -D 官网的不晓得为啥 jekins 打包总会出点问题
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'
// TODO: 上面失效用下面替代 pnpm i unplugin-icons -D
// import { FileSystemIconLoader } from 'unplugin-icons/loaders'
// @see https://unocss.dev/presets/legacy-compat
import presetLegacyCompat from '@unocss/preset-legacy-compat'
import {
  defineConfig,
  presetAttributify,
  presetIcons,
  presetUno,
  transformerDirectives,
  transformerVariantGroup,
} from 'unocss'

import { presetApplet, presetRemRpx, transformerAttributify } from 'unocss-applet'
import { getAllColors } from './scripts/build/ant-colors'

// 这里是为了兼容 eslint --fix 单个文件，不然会找不到svg的目录
let currentDir = process.cwd()
if (currentDir.includes('/src/')) {
  currentDir = currentDir.substring(0, currentDir.lastIndexOf('/src/'))
}
// SVG图标基础目录
const SVG_BASE_DIR = path.join(currentDir, '/src/assets/svg')
// 判断是否是小程序
const isApplet = process.env?.UNI_PLATFORM?.startsWith('mp-') ?? false
const presets: Preset[] = []
const transformers: SourceCodeTransformer[] = []

// 先判断是不是小程序，如果是小程序，则使用小程序的预设和转换器
if (isApplet) {
  // 使用小程序预设
  presets.push(
    // 小程序用官方预设
    presetApplet(),
    // 小程序用 rpx 预设
    // https://github.com/unocss-applet/unocss-applet/tree/main/packages/preset-rem-rpx
    presetRemRpx({ baseFontSize: 16 }),
    // 将颜色函数 (rgb()和hsl()) 从空格分隔转换为逗号分隔，更好的兼容性app端，example：
    // `rgb(255 0 0)` -> `rgb(255, 0, 0)`
    // `rgba(255 0 0 / 0.5)` -> `rgba(255, 0, 0, 0.5)`
    presetLegacyCompat({
      commaStyleColorFunction: true,
    }),
  )
  transformers.push(
    // 小程序用 @apply 功能
    // transformerApplet(),
    transformerDirectives(),
    // 小程序，解决与第三方框架样式冲突问题
    transformerAttributify({
      prefixedOnly: true, // 只支持以 `ft-` 开头的类名
      prefix: 'uno-',
      ignoreAttributes: ['block'],
    }),
  )
}
else {
  presets.push(
    // 非小程序用官方预设
    presetUno(),
    // 解决与第三方框架样式冲突问题
    presetAttributify({
      prefixedOnly: true, // 只支持以 `ft-` 开头的类名
      prefix: 'uno-',
    }),
    // https://github.com/unocss-applet/unocss-applet/tree/main/packages/preset-rem-rpx
    presetRemRpx({ baseFontSize: 16 }),
  )
  transformers.push(
    // 启用 @apply 功能，比如：
    // .custom - div { @apply text-center my-0 font-medium } =>
    // .custom - div { margin-top: 0rem; margin-bottom: 0rem; text-align: center; font-weight: 500;}
    transformerDirectives(),
    // 启用 () 分组功能，比如：
    // <div class="hover:(bg-gray-400 font-medium) font-(light mono)"/> =>
    // <div class="hover:bg-gray-400 hover:font-medium font-light font-mono"/>
    transformerVariantGroup(),
  )
}

/* 公共部分 */
presets.push(
  // 支持图标，需要搭配图标库，eg: @iconify-json/uiw, 使用 <i class="i-uiw-alipay" />
  presetIcons({
    scale: 1.2, // 图标大小
    warn: true, // 警告
    prefix: ['i-'], // 图标前缀
    // 额外的 CSS 属性来控制图标的默认行为，默认内联图标
    extraProperties: {
      display: 'inline-block',
      'vertical-align': 'middle',
    },
    // 全局自定义图标转换
    customizations: {
      transform(svg, collection) {
        // 如果是menu图标，则添加fill="currentColor"
        // 就是可以修改颜色，因为有一些图标是不要修改颜色的
        if (collection === 'menu') {
          return svg.replace(/^<svg /, '<svg fill="currentColor" ')
        }
        return svg
      },
    },
    collections: {
      // 本地SVG图标集合 自动读取SVG_BASE_DIR下面文件夹里面的图标 使用方式为 i-文件夹名称-图标名称
      ...loadLocalSvgCollections(),
      // 按需加载的图标集合 非必须
      // 'ant-design': () => import('@iconify-json/ant-design/icons.json').then(i => i.default),
    },
  }),
)

export default defineConfig({
  // presets 是预设
  presets: [...presets],
  // transformers 是转换器
  transformers: [...transformers],
  // shortcuts 自定义样式快捷方式
  // 具体使用方法，在需要使用到 flex justify-center items-center 这个几个类名时，只需要写一个 flex-center 即可
  shortcuts: [
    { 'flex-center': 'flex justify-center items-center' },
    { 'flex-col-center': 'flex justify-center items-center flex-col' },
  ],
  // rules 的作用是：在全局范围内添加自定义规则
  // 下面的配置适用于有安全区域的设备（如 iPhone X 上的刘海屏）
  // 具体使用也很简单，在需要使用安全区域的元素上添加 p-safe 类名即可
  rules: [
    [
      'p-safe',
      {
        padding:
          'env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)',
      },
    ],
    ['pt-safe', { 'padding-top': 'env(safe-area-inset-top)' }],
    ['pb-safe', { 'padding-bottom': 'env(safe-area-inset-bottom)' }],
    [
      'ptb-safe',
      {
        'padding-top': 'env(safe-area-inset-top)',
        'padding-bottom': 'env(safe-area-inset-bottom)',
      },
    ],
    [
      'm-safe',
      {
        margin:
          'env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)',
      },
    ],
    ['mt-safe', { 'margin-top': 'env(safe-area-inset-top)' }],
    ['mb-safe', { 'margin-bottom': 'env(safe-area-inset-bottom)' }],
    [
      'mtb-safe',
      {
        'margin-top': 'env(safe-area-inset-top)',
        'margin-bottom': 'env(safe-area-inset-bottom)',
      },
    ],
    /** 以下官网规则可自定义转换 */
    /* 例如 m-1 转换为 margin:0.25rem */
    // [/^m-(\d+)$/, ([, d]) => ({margin: `${d / 4}rem`})],
    // [/^p-(\d+)$/, match => ({padding: `${match[1] / 4}rem`})],
    // bg="img-[@/assets/png/cat.png]"
    [/^bg-img-\[(.+)\]$/, ([, value]) => {
      // 替换下划线为正常的路径分隔符
      const path = value.replace(/_/g, '/')
      return {
        'background-image': `url(${path})`,
        'background-repeat': 'no-repeat',
        'background-size': '100% 100%',
      }
    }],
    ['bg-df', { background: 'rgba(0,0,0,0.04)' }],
    ['bg-light', { background: 'rgba(0,0,0,0.02)' }],
    ['bg-body', { background: 'rgba(0,0,0,0.04)' }],
    ['bg-disabled', { background: 'rgba(0,0,0,0.04) !important', cursor: 'not-allowed' }],
    ['bg-disabled-text', { color: 'rgba(0,0,0,0.25) !important' }],
    ['text-xss', { 'font-size': '10px' }],
    [/^text-(.*)$/, ([, c], { theme }) => {
      if (theme[c])
        return { color: theme[c] }
    }],
    [/^text-line-(\d+)$/, ([, value]) => {
      const line = Number.parseInt(value, 10)
      if (line === 1) {
        return {
          overflow: 'hidden',
          'white-space': 'nowrap',
          'text-overflow': 'ellipsis',
        }
      }
      return {
        display: '-webkit-box !important',
        overflow: 'hidden',
        'text-overflow': 'ellipsis',
        'word-break': 'break-all',
        '-webkit-line-clamp': line,
        '-webkit-box-orient': 'vertical !important',
      }
    }],
    // [/^ft-color-(\d+)$/, ([, index]) => {
    //   const numIndex = Number.parseInt(index, 10)
    //   if (!Number.isNaN(numIndex) && numIndex >= 0 && numIndex < brands.length) {
    //     return { color: `${brands[numIndex]} !important` }
    //   }
    // }],
  ],
  theme: {
    // 这里的东西可以使用 text-primary-light, text-primary-dark, text-primary-light, text-primary-dark, text-primary-light, text-primary-dark, text-primary-light, text-primary-dark, text-primary-light, text-primary-dark, text-primary-light, text-primary-dark, text-primary-light, text-primary-dark, text-primary-light, text-primary-dark,
    // 也可以是 bg-primary-light, bg-primary-dark, bg-primary-light, bg-primary-dark, bg-primary-light, bg-primary-dark, bg-primary-light, bg-primary-dark, bg-primary-light, bg-primary-dark, bg-primary-light, bg-primary-dark, bg-primary-light, bg-primary-dark, bg-primary-light, bg-primary-dark, bg-primary-light, bg-primary-dark, bg-primary-light, bg-primary-dark, bg
    colors: {
      ...presetPrimaryColors,
      primary: brands[5],
      success: green[5],
      error: red[4],
      warning: gold[5],
      info: brands[5],
      highlight: red[4],
      processing: green[5],
      'primary-light': brands[0],
      'primary-dark': brands[7],
      df: 'rgba(0,0,0,0.85)',
      main: 'rgba(0,0,0,0.60)',
      second: 'rgba(0,0,0,0.45)',
      placeholder: 'rgba(0,0,0,0.25)',
      'gray-1': '#FFFFFF',
      'gray-2': '#FAFAFA',
      'gray-3': '#F5F5F5',
      'gray-4': '#F0F0F0',
      'gray-5': '#D9D9D9',
      'gray-6': '#BFBFBF',
      'gray-7': '#8C8C8C',
      'gray-8': '#595959',
      'gray-9': '#434343',
      'gray-10': '#262626',
      'gray-11': '#141414',
      'gray-12': '#000000',
      ...getAllColors(),
    },
  },
  // 安全列表 动态图标需要 例如：<div i-menu-home /> 菜单图标是后端返回的需要动态处理
  safelist: [...generateSafeList(['menu'])], // 传入数组参数
})

// 本地 SVG 图标存放目录 用于动态渲染图标 例如：菜单按钮
function generateSafeList(collections: string[]) {
  const safeList: string[] = []
  collections.forEach((collection) => {
    try {
      const dirPath = path.resolve(SVG_BASE_DIR, collection)
      if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) {
        const files = fs.readdirSync(dirPath)
        const icons = files
          .filter(file => file.endsWith('.svg'))
          .map(file => `i-${collection}-${path.basename(file, '.svg')}`)
        safeList.push(...icons)
      }
    } catch (error) {
      console.error(`无法读取图标集合 ${collection}:`, error)
    }
  })

  return safeList
}

// 加载本地SVG图标集合
function loadLocalSvgCollections() {
  const result: Record<string, ReturnType<typeof FileSystemIconLoader>> = {}

  try {
    // 读取SVG_BASE_DIR目录下的所有内容
    const items = fs.readdirSync(SVG_BASE_DIR)

    // 筛选出文件夹
    const collections = items.filter((item) => {
      const itemPath = path.join(SVG_BASE_DIR, item)
      return fs.existsSync(itemPath) && fs.statSync(itemPath).isDirectory()
    })

    // 为每个文件夹创建FileSystemIconLoader
    collections.forEach((collection) => {
      result[collection] = FileSystemIconLoader(path.join(SVG_BASE_DIR, collection))
    })
  } catch (error) {
    console.error(`无法读取SVG图标目录 ${SVG_BASE_DIR}:`, error)
  }
  return result
}

/**
 * 最终这一套组合下来会得到：
 * mp 里面：mt-4 => margin-top: 32rpx  == 16px
 * h5 里面：mt-4 => margin-top: 1rem == 16px
 *
 * 如果是传统方式写样式，则推荐设计稿设置为 750，这样设计稿1px，代码写1rpx。
 * rpx是响应式的，可以让不同设备的屏幕显示效果保持一致。
 */
